# from django.shortcuts import HttpResponse
# from django.utils.deprecation import MiddlewareMixin
# # from rest_framework_jwt.utils import jwt_decode_handler
# import jwt,time
# from jwt.exceptions import ExpiredSignatureError,DecodeError
# from django.http import JsonResponse
# from django.conf import settings
#
# from management.models import Operate_LogModel,PermissionModel
#
# import re,datetime,json
#
# # 导入封装redis
# from utils.redsi_con import redis_conn
# from utils.ip_address.ip_info import CzIp
#
# class MyMiddleware(MiddlewareMixin):
#
#     def dispose_request(self, request):
#         cz = CzIp()
#         permission = PermissionModel.objects.filter(is_delete=False).all()
#
#         # 处理请求
#         def process_request(self, request):
#             try:
#                 x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')  # 判断是否使用代理
#                 if x_forwarded_for:
#                     ip = x_forwarded_for.split(',')[0]  # 使用代理获取真实的ip
#                 else:
#                     ip = request.META.get('REMOTE_ADDR')  # 未使用代理获取IP
#
#                 address = self.cz.get_addr_by_ip(ip)
#                 facility = request.headers.get("User-Agent")
#                 print(f"访问ip {ip} 时间 {datetime.datetime.now()}")
#                 print(f"地址 {address} 设备 {facility}")
#
#                 path = request.path_info
#                 method = request.method.lower()  # GET = get
#                 print(method, path)
#
#                 if re.findall("login|image_code|mobile_code", path, re.I):
#                     return None
#
#                 token = request.headers.get("Authorization")
#                 try:
#                     payload = jwt.decode(token, key=settings.SECRET_KEY, algorithms=['HS256'])
#                     request.session["staff"] = payload
#                 except ExpiredSignatureError:
#                     return JsonResponse({"code": 401, "message": "token过期"})
#                 except DecodeError:
#                     return JsonResponse({"code": 402, "message": "请重新登录"})
#
#                 staff_id = payload.get("id")
#                 print(f"访问用户{staff_id}")
#
#                 # 操作日志
#                 if method != "get":
#                     for i in self.permission:
#                         per_method = i.path.split()[0]
#                         per_path = i.path.split()[1]
#                         if re.findall(per_path, path, re.I) and method == per_method:
#                             Operate_LogModel.objects.create(name=i.name, staff_id=staff_id, path=f"{method} {path}",
#                                                             ip=ip, address=address, facility=facility)
#                             return None
#
#             except Exception as e:
#                 print("请求中间件错误", e)
#                 return JsonResponse({"code": 500, "message": "服务器错误！"}, status=200)
#                 return None










# import socket
# import struct
#
#
# class CzIp:
#     def __init__(self, db_file='utils/ip_address/qqwry.dat'):
#         self.f_db = open(db_file, "rb")
#         bs = self.f_db.read(8)
#         (self.first_index, self.last_index) = struct.unpack('II', bs)
#         self.index_count = int((self.last_index - self.first_index) / 7 + 1)
#         self.cur_start_ip = None
#         self.cur_end_ip_offset = None
#         self.cur_end_ip = None
#         # print(self.get_version(), " 纪录总数: %d 条 "%(self.index_count))
#
#     def get_version(self):
#         '''
#         获取版本信息，最后一条IP记录 255.255.255.0-255.255.255.255 是版本信息
#         :return: str
#         '''
#         s = self.get_addr_by_ip(0xffffff00)
#         # print(s)
#         return s
#
#     def _get_area_addr(self, offset=0):
#         if offset:
#             self.f_db.seek(offset)
#         bs = self.f_db.read(1)
#         (byte,) = struct.unpack('B', bs)
#         if byte == 0x01 or byte == 0x02:
#             p = self.getLong3()
#             if p:
#                 return self.get_offset_string(p)
#             else:
#                 return ""
#         else:
#             self.f_db.seek(-1, 1)
#             return self.get_offset_string(offset)
#
#     def _get_addr(self, offset):
#         '''
#         获取offset处记录区地址信息(包含国家和地区)
#         如果是中国ip，则是 "xx省xx市 xxxxx地区" 这样的形式
#         (比如:"福建省 电信", "澳大利亚 墨尔本Goldenit有限公司")
#         :param offset:
#         :return:str
#         '''
#         self.f_db.seek(offset + 4)
#         bs = self.f_db.read(1)
#         (byte,) = struct.unpack('B', bs)
#         if byte == 0x01:    # 重定向模式1
#             country_offset = self.getLong3()
#             self.f_db.seek(country_offset)
#             bs = self.f_db.read(1)
#             (b,) = struct.unpack('B', bs)
#             if b == 0x02:
#                 country_addr = self.get_offset_string(self.getLong3())
#                 self.f_db.seek(country_offset + 4)
#             else:
#                 country_addr = self.get_offset_string(country_offset)
#             area_addr = self._get_area_addr()
#         elif byte == 0x02:  # 重定向模式2
#             country_addr = self.get_offset_string(self.getLong3())
#             area_addr = self._get_area_addr(offset + 8)
#         else:   # 字符串模式
#             country_addr = self.get_offset_string(offset + 4)
#             area_addr = self._get_area_addr()
#         return country_addr + " " + area_addr
#
#     def dump(self, first, last):
#         '''
#         打印数据库中索引为first到索引为last(不包含last)的记录
#         :param first:
#         :param last:
#         :return:
#         '''
#         if last > self.index_count:
#             last = self.index_count
#         for index in range(first, last):
#             offset = self.first_index + index * 7
#             self.f_db.seek(offset)
#             buf = self.f_db.read(7)
#             (ip, of1, of2) = struct.unpack("IHB", buf)
#             address = self._get_addr(of1 + (of2 << 16))
#             print("%d %s %s" % (index, self.ip2str(ip), address))
#
#     def _set_ip_range(self, index):
#         offset = self.first_index + index * 7
#         self.f_db.seek(offset)
#         buf = self.f_db.read(7)
#         (self.cur_start_ip, of1, of2) = struct.unpack("IHB", buf)
#         self.cur_end_ip_offset = of1 + (of2 << 16)
#         self.f_db.seek(self.cur_end_ip_offset)
#         buf = self.f_db.read(4)
#         (self.cur_end_ip,) = struct.unpack("I", buf)
#
#     def get_addr_by_ip(self, ip):
#         '''
#         通过ip查找其地址
#         :param ip: (int or str)
#         :return: str
#         '''
#         if type(ip) == str:
#             ip = self.str2ip(ip)
#         L = 0
#         R = self.index_count - 1
#         while L < R - 1:
#             M = int((L + R) / 2)
#             self._set_ip_range(M)
#             if ip == self.cur_start_ip:
#                 L = M
#                 break
#             if ip > self.cur_start_ip:
#                 L = M
#             else:
#                 R = M
#         self._set_ip_range(L)
#         # version information, 255.255.255.X, urgy but useful
#         if ip & 0xffffff00 == 0xffffff00:
#             self._set_ip_range(R)
#         if self.cur_start_ip <= ip <= self.cur_end_ip:
#             address = self._get_addr(self.cur_end_ip_offset)
#         else:
#             address = "未找到该IP的地址"
#         return address
#
#     def get_ip_range(self, ip):
#         '''
#         返回ip所在记录的IP段
#         :param ip: ip(str or int)
#         :return: str
#         '''
#         if type(ip) == str:
#             ip = self.str2ip(ip)
#         self.get_addr_by_ip(ip)
#         range = self.ip2str(self.cur_start_ip) + ' - ' \
#                 + self.ip2str(self.cur_end_ip)
#         return range
#
#     def get_offset_string(self, offset=0):
#         '''
#         获取文件偏移处的字符串(以'\0'结尾)
#         :param offset: 偏移
#         :return: str
#         '''
#         if offset:
#             self.f_db.seek(offset)
#         bs = b''
#         ch = self.f_db.read(1)
#         (byte,) = struct.unpack('B', ch)
#         while byte != 0:
#             bs += ch
#             ch = self.f_db.read(1)
#             (byte,) = struct.unpack('B', ch)
#         return bs.decode('gbk')
#
#     def ip2str(self, ip):
#         '''
#         整数IP转化为IP字符串
#         :param ip:
#         :return:
#         '''
#         return str(ip >> 24) + '.' + str((ip >> 16) & 0xff) + '.' + str((ip >> 8) & 0xff) + '.' + str(ip & 0xff)
#
#     def str2ip(self, s):
#         '''
#         IP字符串转换为整数IP
#         :param s:
#         :return:
#         '''
#         (ip,) = struct.unpack('I', socket.inet_aton(s))
#         return ((ip >> 24) & 0xff) | ((ip & 0xff) << 24) | ((ip >> 8) & 0xff00) | ((ip & 0xff00) << 8)
#
#     def getLong3(self, offset=0):
#         '''
#         3字节的数值
#         :param offset:
#         :return:
#         '''
#         if offset:
#             self.f_db.seek(offset)
#         bs = self.f_db.read(3)
#         (a, b) = struct.unpack('HB', bs)
#         return (b << 16) + a
#
#
#
# if __name__ == '__main__':
#     cz = CzIp()
#     # print(cz.get_version())
#     ip = '106.224.149.75'
#     # print(cz.get_ip_range(ip))
#     print(cz.get_addr_by_ip(ip))